package ac.java.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.DOMReader;
import org.dom4j.io.SAXReader;
import org.xml.sax.SAXException;

public class XmlDom4j {
	// xml 解析方式
	public static String PARSE_XML_TYPE = "DOM"; // "SAX"
	private static Logger LOG = Logger.getLogger("Xml");
	
	/**
	 * SAX方式 读取XML
	 * @param file
	 * @return
	 * @throws FileNotFoundException
	 * @throws DocumentException
	 */
	public static Document getDocBySax(File file) throws FileNotFoundException, DocumentException
	{
		SAXReader sr = new SAXReader();
		
		InputStream is = new FileInputStream(file);
		Document doc = sr.read(is);
		try {
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return doc;
	}
	
	/**
	 * DOM方式 读取XML
	 * @param file
	 * @return
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 * @throws IOException
	 */
	public static Document getDocByDom(File file) throws ParserConfigurationException, SAXException, IOException
	{
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		org.w3c.dom.Document w3cDoc = db.parse(file);
		DOMReader dr = new DOMReader();
		Document doc = dr.read(w3cDoc);
		return doc;
	}
	/**
	 * 将map转换成xml
	 * @param map
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String getRsXml(Status status,List rsmapList,List grmapList,Integer total){
		
		
		Document xml = DocumentHelper.createDocument();
	     Element dataRoot = xml.addElement("data");
		//status begin
		Element statusElement = dataRoot.addElement("status");
		statusElement.addElement("exceptionCode").addText(status.getExceptionCode());
		statusElement.addElement("exceptionMsg").addText(status.getExceptionMsg());
		//status end
		
		//count begin
		if(total!=null){
			dataRoot.addElement("count").addText(total.toString());
		}
		//count end
		
		
		//rs begin
		if(rsmapList!=null&&rsmapList.size()>0){
		Element rsRoot = dataRoot.addElement("rs");
		for(int i=0;i<rsmapList.size();i++){
		Element rowRoot = rsRoot.addElement("row");
		Map rsmap=(Map)rsmapList.get(i);
		Iterator rsKeyIt = rsmap.keySet().iterator();
		while(rsKeyIt.hasNext()){
			String key=(String)rsKeyIt.next();
			rowRoot.addElement(key).addText((String)rsmap.get(key));		
		  }
		 }
		}
		//rs end
		
		
		//grs begin
		if(grmapList!=null&&grmapList.size()>0){
			Element grsRoot = dataRoot.addElement("grs");
		for(int i=0;i<grmapList.size();i++){
			Element groupRoot = grsRoot.addElement("group");
		    Map grmap=(Map)grmapList.get(i);
		    Iterator grsKeyIt = grmap.keySet().iterator();
		    while(grsKeyIt.hasNext()){
		    	String key=(String)grsKeyIt.next();
		    	groupRoot.addElement(key).addText((String)grmap.get(key));
		    }
		  }		
		}
		//grs end
		
		return xml.asXML();
	
	}
	//shelley
	public static Document getDocByXml(String path){
		File xml = new File(path);
		Document doc = null;
		try {
			if (PARSE_XML_TYPE.equals("DOM")) {
				doc = getDocByDom(xml);
			} else {
				doc = getDocBySax(xml);
			}
		} catch (Exception e) {
			LOG.error(e.toString());
			LOG.error("load_xml_path" + path);
			return null;
		}	
		return doc;
	}
	public static Map<String, Object> getMapsByXml(String path){
		File xml = new File(path);
		Document doc = null;
		try {
			if (PARSE_XML_TYPE.equals("DOM")) {
				doc = getDocByDom(xml);
			} else {
				doc = getDocBySax(xml);
			}
		} catch (Exception e) {
			LOG.error(e.toString());
			LOG.error("load_xml_path" + path);
			return null;
		}
		
		Map<String, Object> maps = getMapsByDoc(doc);
		
		
		return maps;
	}
	
	public static Map<String, Object> getMapsByDoc(Document doc){
		Map<String, Object> map = new HashMap<String, Object>();
		if(doc == null)
			return map;
		Element root = doc.getRootElement();
		for (Iterator iterator = root.elementIterator(); iterator.hasNext();) {
			Element e = (Element) iterator.next();
			List list = e.elements();
			if(list.size() > 0){
				map.put(e.getName(), getMapByDom(e));
			}else
				map.put(e.getName(), e.getText());
		}
		return map;
	}
	
	public static Map getMapByDom(Element e){
		Map	map = new HashMap();
		List list = e.elements();
		if(list.size() > 0){
			for (int i = 0;i < list.size(); i++) {
				Element iter = (Element) list.get(i);
				List mapList = new ArrayList();
				
				if(iter.elements().size() > 0){
					Map m = getMapByDom(iter);
					if(map.get(iter.getName()) != null){
						Object obj = map.get(iter.getName());
						if(!obj.getClass().getName().equals("java.util.ArrayList")){
							mapList = new ArrayList();
							mapList.add(obj);
							mapList.add(m);
						}
						if(obj.getClass().getName().equals("java.util.ArrayList")){
							mapList = (List) obj;
							mapList.add(m);
						}
						map.put(iter.getName(), mapList);
					}else
						map.put(iter.getName(), m);
				}
				else{
					if(map.get(iter.getName()) != null){
						Object obj = map.get(iter.getName());
						if(!obj.getClass().getName().equals("java.util.ArrayList")){
							mapList = new ArrayList();
							mapList.add(obj);
							mapList.add(iter.getText());
						}
						if(obj.getClass().getName().equals("java.util.ArrayList")){
							mapList = (List) obj;
							mapList.add(iter.getText());
						}
						map.put(iter.getName(), mapList);
					}else
						map.put(iter.getName(), iter.getText());
				}
			}
		}else
			map.put(e.getName(), e.getText());
		return map;
	}
	
	public static List<String> getListByDoc(String path)
	{
		File file = new File(path);
		try {
			List<String> list = new ArrayList<String>();
			Document doc = getDocByDom(file);
			Element root = doc.getRootElement();
			for (Iterator iterator = root.elementIterator(); iterator.hasNext();) {
				Element e = (Element) iterator.next();
				list.add(e.getText());
			}
			
			return list;
		} catch (Exception e) {
		
			return null;
		}
	}
}
